<script setup>
import { reactive, ref, computed, onMounted } from 'vue'
import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Clock, Delete, Promotion, Plus, RefreshLeft, Search, Check } from '@element-plus/icons-vue'

// 设备检测和安全区域适配
const isMobile = computed(() => window.innerWidth <= 768)
const isPortrait = computed(() => window.innerHeight > window.innerWidth)
const safeAreaInsetBottom = ref(0)

// 检测设备安全区域
onMounted(() => {
  // 获取安全区域高度（适配刘海屏等设备）
  safeAreaInsetBottom.value = window.safeAreaInsets?.bottom || 0
  
  // 监听窗口大小变化
  const handleResize = () => {
    safeAreaInsetBottom.value = window.safeAreaInsets?.bottom || 0
  }
  
  window.addEventListener('resize', handleResize)
  return () => window.removeEventListener('resize', handleResize)
})
// 移动端振动反馈
const triggerVibration = () => {
  if (isMobile.value && navigator.vibrate) {
    navigator.vibrate(10)
  }
}

// 响应式数据
const form = reactive({
  topic: 'server\\public',
  message: '',
  qos: 0,
  retained: true, // 默认启用retained，确保消息能被后续订阅者接收
  messageFormat: 'text' // 新增：消息格式选择
})

// 消息格式选项
const messageFormats = ref([
  { value: 'text', label: '纯文本', description: '直接发送文本内容' },
  { value: 'json', label: 'JSON格式', description: '发送JSON对象' },
  { value: 'keyvalue', label: '键值对', description: 'key=value&key2=value2' },
  { value: 'csv', label: 'CSV格式', description: '逗号分隔的值' },
  { value: 'command', label: '指令格式', description: 'command:param1:param2' },
  { value: 'args', label: '命令行参数', description: '--key value --key2 value2' }
])

const loading = ref(false)
const showHistoryPanel = ref(false)

// 消息历史
const messageHistory = ref([])

// 快捷指令
const quickCommands = ref([])
const showEditDialog = ref(false)
const editingCommand = ref(null)
const newCommandName = ref('')
const newCommandTopic = ref('')
const newCommandMessage = ref('')
const newCommandQos = ref(0)
const newCommandRetained = ref(false)
const newCommandFormat = ref('text') // 新增：快捷指令的消息格式

// 获取消息占位符
const getMessagePlaceholder = (format) => {
  const placeholders = {
    'text': '输入任意文本内容',
    'json': '{"key": "value", "number": 123}',
    'keyvalue': 'key1=value1\nkey2=value2',
    'csv': 'value1,value2,value3',
    'command': 'command\nparam1\nparam2',
    'args': 'key1\nkey2\nkey3'
  }
  return placeholders[format] || '输入消息内容'
}

// 获取格式提示信息
const getFormatHint = (format) => {
  const hints = {
    'text': '直接发送文本内容，无需特殊格式',
    'json': '输入有效的JSON格式，每行一个键值对',
    'keyvalue': '每行一个键值对，格式：key=value',
    'csv': '每行一个值，用逗号分隔',
    'command': '每行一个参数，第一行为命令名',
    'args': '每行一个参数名，会自动添加--前缀'
  }
  return hints[format] || ''
}

// 安全地获取消息的字符串表示
const getMessageDisplay = (message, maxLength = 50) => {
  if (!message) return ''
  
  let messageStr = ''
  if (typeof message === 'string') {
    messageStr = message
  } else if (typeof message === 'object') {
    try {
      messageStr = JSON.stringify(message)
    } catch (e) {
      messageStr = String(message)
    }
  } else {
    messageStr = String(message)
  }
  
  if (messageStr.length > maxLength) {
    return messageStr.substring(0, maxLength) + '...'
  }
  return messageStr
}

// 获取消息类型标签
const getMessageTypeLabel = (format) => {
  const labels = {
    'text': '文本',
    'json': 'JSON',
    'keyvalue': '键值对',
    'csv': 'CSV',
    'command': '指令',
    'args': '参数'
  }
  return labels[format] || '文本'
}

// 获取消息类型标签颜色
const getMessageTypeTagType = (format) => {
  const types = {
    'text': '',
    'json': 'success',
    'keyvalue': 'warning',
    'csv': 'info',
    'command': 'danger',
    'args': 'primary'
  }
  return types[format] || ''
}

// 消息格式转换函数
const convertMessageFormat = (message, format) => {
  if (!message.trim()) return message
  
  switch (format) {
    case 'json':
      try {
        // 尝试解析为JSON，如果失败则包装为JSON对象
        const parsed = JSON.parse(message)
        return parsed
      } catch {
        return { content: message, type: 'text' }
      }
    
    case 'keyvalue':
      // 将文本转换为键值对格式
      const lines = message.split('\n').filter(line => line.trim())
      const obj = {}
      lines.forEach(line => {
        if (line.includes('=')) {
          const [key, value] = line.split('=', 2)
          obj[key.trim()] = value.trim()
        }
      })
      return Object.keys(obj).length > 0 ? obj : message
    
    case 'csv':
      // 将文本转换为CSV格式
      const values = message.split('\n').map(line => line.trim()).filter(line => line)
      return values.join(',')
    
    case 'command':
      // 将文本转换为指令格式
      const parts = message.split('\n').map(line => line.trim()).filter(line => line)
      return parts.join(':')
    
    case 'args':
      // 将文本转换为命令行参数格式
      const args = message.split('\n').map(line => line.trim()).filter(line => line)
      return args.map(arg => `--${arg}`).join(' ')

    case 'text':
    default:
      return message
  }
}

// 方法
const publish = async () => {
  triggerVibration()
  
  try {
    loading.value = true
    
    // 根据选择的格式转换消息
    const convertedMessage = convertMessageFormat(form.message, form.messageFormat)
    
    const publishData = { 
      topic: form.topic,
      message: convertedMessage,
      qos: form.qos,
      retained: form.retained
    }
    
    await axios.post('/api/publish', publishData)
    ElMessage.success('发布成功')
    
    // 添加到历史记录
    addToHistory(publishData)
    
    // 清空消息内容
    form.message = ''
  } catch (e) {
    ElMessage.error('发布失败: ' + (e?.response?.data?.message || e.message))
  } finally {
    loading.value = false
  }
}

// 添加到历史记录
const addToHistory = (publishData) => {
  const historyItem = {
    id: Date.now(),
    timestamp: new Date().toLocaleString(),
    ...publishData
  }
  
  messageHistory.value.unshift(historyItem)
  
  // 限制历史记录数量
  if (messageHistory.value.length > 50) {
    messageHistory.value = messageHistory.value.slice(0, 50)
  }
}

// 重新发布历史消息
const republishHistory = (historyItem) => {
  triggerVibration()
  form.topic = historyItem.topic
  form.message = historyItem.message
  form.qos = historyItem.qos
  form.retained = historyItem.retained
  showHistoryPanel.value = false
  ElMessage.success('已加载历史消息')
}

// 清空历史记录
const clearHistory = async () => {
  triggerVibration()
  try {
    await ElMessageBox.confirm('确定要清空所有历史记录吗？', '确认清空', {
      confirmButtonText: '清空',
      cancelButtonText: '取消',
      type: 'warning'
    })
    
    messageHistory.value = []
    ElMessage.success('历史记录已清空')
  } catch (e) {
    // 用户取消
  }
}

// 快捷指令相关方法
const loadQuickCommands = () => {
  const saved = localStorage.getItem('mqtt-quick-commands')
  if (saved) {
    try {
      quickCommands.value = JSON.parse(saved) || []
    } catch (e) {
      console.warn('加载快捷指令失败:', e)
    }
  }
}

const saveQuickCommands = () => {
  localStorage.setItem('mqtt-quick-commands', JSON.stringify(quickCommands.value))
}

const addQuickCommand = () => {
  triggerVibration()
  editingCommand.value = null
  newCommandName.value = ''
  newCommandTopic.value = '' // 默认为空，让用户输入
  newCommandMessage.value = ''
  newCommandQos.value = 0
  newCommandRetained.value = false
  newCommandFormat.value = 'text' // 默认格式
  showEditDialog.value = true
}

const editQuickCommand = (command) => {
  triggerVibration()
  editingCommand.value = command
  newCommandName.value = command.name
  newCommandTopic.value = command.topic
  newCommandMessage.value = command.message
  newCommandQos.value = command.qos
  newCommandRetained.value = command.retained
  newCommandFormat.value = command.format || 'text' // 兼容旧数据
  showEditDialog.value = true
}

const saveCommand = () => {
  triggerVibration()
  
  if (!newCommandName.value.trim()) {
    ElMessage.warning('请输入指令名称')
    return
  }
  if (!newCommandTopic.value.trim()) {
    ElMessage.warning('请输入主题')
    return
  }

  const commandData = {
    id: editingCommand.value ? editingCommand.value.id : Date.now(),
    name: newCommandName.value.trim(),
    topic: newCommandTopic.value.trim(),
    message: newCommandMessage.value,
    format: newCommandFormat.value, // 新增：消息格式
    qos: newCommandQos.value,
    retained: newCommandRetained.value
  }

  if (editingCommand.value) {
    // 编辑现有指令
    const index = quickCommands.value.findIndex(cmd => cmd.id === editingCommand.value.id)
    if (index !== -1) {
      quickCommands.value[index] = commandData
    }
    ElMessage.success('指令已更新')
  } else {
    // 添加新指令
    quickCommands.value.push(commandData)
    ElMessage.success('指令已添加')
  }

  saveQuickCommands()
  showEditDialog.value = false
}

const deleteCommand = async (command) => {
  triggerVibration()
  try {
    await ElMessageBox.confirm(`确定要删除指令 "${command.name}" 吗？`, '确认删除', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning'
    })
    
    const index = quickCommands.value.findIndex(cmd => cmd.id === command.id)
    if (index !== -1) {
      quickCommands.value.splice(index, 1)
      saveQuickCommands()
      ElMessage.success('指令已删除')
    }
  } catch (e) {
    // 用户取消
  }
}

const executeCommandPublish = async (command) => {
  triggerVibration()
  try {
    loading.value = true
    
    // 根据快捷指令的格式转换消息
    const format = command.format || 'text'
    const convertedMessage = convertMessageFormat(command.message, format)
    
    const publishData = {
      topic: command.topic,
      message: convertedMessage,
      qos: command.qos,
      retained: command.retained
    }
    
    console.log('发布快捷指令:', publishData) // 添加调试日志
    console.log('原始消息:', command.message)
    console.log('转换后消息:', convertedMessage)
    console.log('使用格式:', format)
    
    const response = await axios.post('/api/publish', publishData)
    console.log('发布响应:', response.data) // 添加响应日志
    
    ElMessage.success(`快捷指令发布成功: ${command.topic}`)
    addToHistory(publishData)
  } catch (e) {
    console.error('快捷指令发布失败:', e) // 添加错误日志
    ElMessage.error('发布失败: ' + (e?.response?.data?.message || e.message))
  } finally {
    loading.value = false
  }
}

const executeCommandSubscribe = async (command) => {
  try {
    await axios.post('/api/subscribe', { 
      topic: command.topic, 
      qos: command.qos 
    })
    ElMessage.success(`已订阅主题: ${command.topic}`)
  } catch (e) {
    ElMessage.error('订阅失败: ' + (e?.response?.data?.message || e.message))
  }
}

onMounted(() => {
  // 从localStorage加载历史记录
  const savedHistory = localStorage.getItem('mqtt-history')
  if (savedHistory) {
    messageHistory.value = JSON.parse(savedHistory)
  }
  // 加载快捷指令
  loadQuickCommands()
})

// 监听数据变化，保存到localStorage
import { watch } from 'vue'
watch(messageHistory, (newHistory) => {
  localStorage.setItem('mqtt-history', JSON.stringify(newHistory))
}, { deep: true })

watch(quickCommands, () => {
  saveQuickCommands()
}, { deep: true })

</script>

<template>
  <div class="custom-publish">
    <!-- 移动端工具栏 -->
    <div class="mobile-toolbar" :style="{ paddingBottom: `${safeAreaInsetBottom.value}px` }">
      <el-button 
        @click="showHistoryPanel = !showHistoryPanel" 
        :type="showHistoryPanel ? 'primary' : ''"
        size="large"
        class="mobile-btn pulse-effect"
      >
        <el-icon><Clock /></el-icon>
        历史记录
      </el-button>
    </div>

    <!-- 主要内容区域 -->
    <div class="main-content">
      <!-- 发布表单 -->
      <div class="publish-form">
        <el-card shadow="never">
          <template #header>
            <div class="card-header">
              <span>发布消息</span>
              <el-button v-if="form.message" @click="form.message = ''" size="small" type="danger" text>
                <el-icon><Delete /></el-icon>
                清空
              </el-button>
            </div>
          </template>
          
          <el-form label-width="80px" class="publish-form-content">
            <el-form-item label="主题">
              <el-input 
                v-model="form.topic"
                placeholder="输入MQTT主题"
                size="large"
                clearable
                :class="{ 'mobile-input': isMobile }"
              />
            </el-form-item>
            
            <el-form-item label="消息格式">
              <el-select 
                v-model="form.messageFormat" 
                placeholder="选择消息格式"
                size="large"
                style="width: 100%"
              >
                <el-option 
                  v-for="format in messageFormats" 
                  :key="format.value" 
                  :value="format.value" 
                  :label="format.label"
                >
                  <div>
                    <div>{{ format.label }}</div>
                    <div style="font-size:12px;color:#999;">{{ format.description }}</div>
                  </div>
                </el-option>
              </el-select>
            </el-form-item>
            
            <el-form-item label="消息">
              <el-input 
                v-model="form.message" 
                type="textarea" 
                :rows="isMobile ? 8 : 6" 
                :placeholder="getMessagePlaceholder(form.messageFormat)"
                show-word-limit
                maxlength="10000"
                size="large"
                :class="{ 'mobile-textarea': isMobile }"
              />
              <div class="format-hint">
                {{ getFormatHint(form.messageFormat) }}
              </div>
            </el-form-item>
            
            <el-form-item label="QoS">
              <el-select v-model="form.qos" size="large" style="width: 100%">
                <el-option :value="0" label="0 - 最多一次" />
                <el-option :value="1" label="1 - 至少一次" />
                <el-option :value="2" label="2 - 恰好一次" />
              </el-select>
            </el-form-item>
            
            <el-form-item label="保留" class="switch-item">
              <el-switch v-model="form.retained" size="large" />
              <span class="form-tip">消息将被保留供后续订阅者接收</span>
            </el-form-item>
            
            <el-form-item class="publish-button">
              <el-button 
                type="primary" 
                :loading="loading" 
                @click="publish" 
                size="large"
                class="publish-btn pulse-effect"
              >
                <el-icon><Promotion /></el-icon>
                发布消息
              </el-button>
            </el-form-item>
          </el-form>
        </el-card>

        <!-- 快捷指令区域 -->
        <el-card shadow="never" style="margin-top: 16px;">
          <template #header>
            <div class="card-header">
              <span>快捷发布</span>
            </div>
          </template>
          
          <!-- 无指令时显示 -->
          <div v-if="quickCommands.length === 0" class="empty-commands">
            <div class="empty-content">
              <el-button type="primary" @click="addQuickCommand" size="large">
                <el-icon><Plus /></el-icon>
                添加快捷指令
              </el-button>
            </div>
          </div>
          
          <!-- 有指令时显示 -->
          <div v-else class="commands-list">
            <div class="commands-header">
              <div class="command-item touchable" v-for="command in quickCommands" :key="command.id">
                <div class="command-info">
                  <div class="command-name" @click="executeCommandPublish(command)">
                    <el-icon style="margin-right: 4px;"><RefreshLeft /></el-icon>
                    {{ command.name }}
                  </div>
                  <div class="command-topic">{{ command.topic }}</div>
                  <div class="command-format">
                    <el-tag :type="getMessageTypeTagType(command.format || 'text')" size="small">
                      {{ getMessageTypeLabel(command.format || 'text') }}
                    </el-tag>
                  </div>
                </div>
                <div class="command-actions" :class="{ 'mobile-command-actions': isMobile }">
                  <el-tooltip v-if="!isMobile" effect="dark" content="编辑" placement="top" :show-after="500">
                    <el-button size="small" @click="editQuickCommand(command)" circle>
                      <el-icon><Search /></el-icon>
                    </el-button>
                  </el-tooltip>
                  <el-button v-else size="small" @click="editQuickCommand(command)" circle>
                    <el-icon><Search /></el-icon>
                  </el-button>
                  <el-tooltip v-if="!isMobile" effect="dark" content="删除" placement="top" :show-after="500">
                    <el-button size="small" type="danger" @click="deleteCommand(command)" circle>
                      <el-icon><Delete /></el-icon>
                    </el-button>
                  </el-tooltip>
                  <el-button v-else size="small" type="danger" @click="deleteCommand(command)" circle>
                    <el-icon><Delete /></el-icon>
                  </el-button>
                </div>
              </div>
              <el-button type="primary" @click="addQuickCommand" size="small" :class="{ 'mobile-add-btn': isMobile }">
                <el-icon><Plus /></el-icon>
                {{ isMobile ? '添加' : '' }}
              </el-button>
            </div>
          </div>
        </el-card>
      </div>

      <!-- 右侧面板 -->
      <div class="side-panels">
        <!-- 历史记录面板 -->
        <el-card v-show="showHistoryPanel" shadow="never" class="side-panel">
          <template #header>
            <div class="card-header">
              <span>发布历史</span>
              <el-button @click="clearHistory" size="small" type="danger" text>
                <el-icon><Delete /></el-icon>
                清空
              </el-button>
            </div>
          </template>
          
          <div class="history-list">
            <div 
              v-for="item in messageHistory" 
              :key="item.id" 
              class="history-item touchable"
              @click="republishHistory(item)"
            >
              <div class="history-info">
                <div class="history-topic">{{ item.topic }}</div>
                <div class="history-message">{{ getMessageDisplay(item.message, isMobile ? 30 : 50) }}</div>
                <div class="history-meta">
                  {{ item.timestamp }} | QoS: {{ item.qos }}
                </div>
              </div>
              <div class="history-actions">
                <el-button 
                  @click.stop="republishHistory(item)" 
                  size="small" 
                  type="primary" 
                  :class="{ 'mobile-republish-btn': isMobile }"
                  :icon="RefreshLeft"
                >
                  {{ isMobile ? '' : '重新发布' }}
                </el-button>
              </div>
            </div>
            <el-empty v-if="messageHistory.length === 0" description="暂无历史记录" />
          </div>
        </el-card>
      </div>
    </div>

    <!-- 编辑指令对话框 -->
    <el-dialog 
      v-model="showEditDialog" 
      :title="editingCommand ? '编辑指令' : '添加快捷指令'"
      :width="isMobile ? '90%' : '500px'"
      :fullscreen="isPortrait && isMobile"
    >
      <el-form label-width="80px">
        <el-form-item label="名称" required>
          <el-input v-model="newCommandName" placeholder="请输入指令名称" clearable />
        </el-form-item>
        <el-form-item label="主题" required>
          <el-input v-model="newCommandTopic" placeholder="请输入主题" clearable />
        </el-form-item>
        <el-form-item label="消息格式">
          <el-select v-model="newCommandFormat" :style="isMobile ? { width: '100%' } : { width: '200px' }" placeholder="选择消息格式">
            <el-option 
              v-for="format in messageFormats" 
              :key="format.value" 
              :value="format.value" 
              :label="format.label"
            >
              <div>
                <div>{{ format.label }}</div>
                <div style="font-size:12px;color:#999;">{{ format.description }}</div>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="消息">
          <el-input 
            v-model="newCommandMessage" 
            type="textarea" 
            :rows="4" 
            :placeholder="getMessagePlaceholder(newCommandFormat)"
          />
          <div class="format-hint">
            {{ getFormatHint(newCommandFormat) }}
          </div>
        </el-form-item>
        <el-form-item label="QoS">
          <el-select v-model="newCommandQos" style="width:120px;">
            <el-option :value="0" label="0 - 最多一次" />
            <el-option :value="1" label="1 - 至少一次" />
            <el-option :value="2" label="2 - 恰好一次" />
          </el-select>
        </el-form-item>
        <el-form-item label="保留">
          <el-switch v-model="newCommandRetained" />
        </el-form-item>
      </el-form>
      
      <template #footer>
        <el-button @click="showEditDialog = false">取消</el-button>
        <el-button type="primary" @click="saveCommand">
          {{ editingCommand ? '更新' : '添加' }}
        </el-button>
      </template>
    </el-dialog>

  </div>
</template>

<style scoped>
/* 基础变量定义 */
:root {
  --primary-color: #409eff;
  --success-color: #67c23a;
  --warning-color: #e6a23c;
  --danger-color: #f56c6c;
  --info-color: #909399;
  --border-color: #ebeef5;
  --text-primary: #303133;
  --text-regular: #606266;
  --text-secondary: #909399;
  --background-color: #ffffff;
  --background-light: #f5f7fa;
  --border-radius: 8px;
  --touch-feedback: 0.2s;
  --pulse-duration: 0.5s;
}

/* 深色模式适配 */
html.dark {
  --background-color: #1a1a1a;
  --background-light: #2c2c2c;
  --text-primary: #ffffff;
  --text-regular: #cccccc;
  --text-secondary: #999999;
  --border-color: #444444;
}

.custom-publish {
  min-height: calc(100vh - 200px);
  display: flex;
  flex-direction: column;
  background-color: var(--background-color);
  color: var(--text-primary);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.toolbar {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 16px;
  padding: 12px;
  background: var(--background-light);
  border-radius: var(--border-radius);
}

.main-content {
  flex: 1;
  display: flex;
  gap: 16px;
  min-height: 0;
}

.publish-form {
  flex: 1;
  min-width: 0;
}

.side-panels {
  width: 300px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.side-panel {
  flex: 1;
  min-height: 0;
  background-color: var(--background-color);
  border-radius: var(--border-radius);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 16px;
  margin-bottom: 8px;
}

.header-actions {
  display: flex;
  gap: 8px;
}

.history-list {
  /* 移除固定高度和嵌套滚动，避免与主页面滚动冲突 */
  max-height: none;
  overflow: visible;
  padding-right: 8px;
}

/* 滚动条样式优化 */
.history-list::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.history-list::-webkit-scrollbar-thumb {
  background: var(--border-color);
  border-radius: 3px;
}

.history-list::-webkit-scrollbar-track {
  background: var(--background-light);
  border-radius: 3px;
}

.history-item {
  padding: 12px;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  margin-bottom: 8px;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  transition: all var(--touch-feedback);
}

.history-item:hover {
  border-color: var(--primary-color);
  background: rgba(64, 158, 255, 0.05);
}

.history-item.touchable:active {
  transform: scale(0.98);
}

.history-info {
  flex: 1;
  min-width: 0;
  margin-right: 8px;
}

.history-topic {
  font-weight: 600;
  margin-bottom: 4px;
  color: var(--text-primary);
  font-size: 14px;
}

.history-message {
  font-size: 12px;
  color: var(--text-regular);
  margin-bottom: 4px;
  word-break: break-all;
  line-height: 1.4;
}

.history-meta {
  font-size: 11px;
  color: var(--text-secondary);
}

.history-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.mobile-republish-btn {
  padding: 8px;
  font-size: 16px;
  min-width: 40px;
  height: 40px;
}

.form-tip {
  font-size: 12px;
  color: var(--text-secondary);
  margin-left: 8px;
}

.format-hint {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 4px;
  padding: 8px;
  background: var(--background-light);
  border-radius: var(--border-radius);
  border-left: 3px solid var(--primary-color);
  line-height: 1.5;
}

/* 快捷指令样式 */
.empty-commands {
  padding: 40px 20px;
  text-align: center;
}

.empty-content {
  display: flex;
  justify-content: center;
  align-items: center;
}

.commands-list {
  padding: 16px 0;
}

.commands-header {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.command-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius);
  background: var(--background-light);
  transition: all var(--touch-feedback);
  width: 100%;
}

.command-item:hover {
  border-color: var(--primary-color);
  background: rgba(64, 158, 255, 0.05);
}

.command-item.touchable:active {
  transform: scale(0.98);
}

.command-info {
  flex: 1;
  min-width: 0;
}

.command-name {
  cursor: pointer;
  font-weight: 500;
  color: var(--text-primary);
  padding: 4px 8px;
  border-radius: 4px;
  transition: background-color var(--touch-feedback);
  margin-bottom: 2px;
  display: flex;
  align-items: center;
}

.command-name:hover {
  background: rgba(64, 158, 255, 0.1);
}

.command-topic {
  font-size: 12px;
  color: var(--text-secondary);
  padding: 0 8px;
  word-break: break-all;
}

.command-format {
  margin-top: 4px;
  padding: 0 8px;
}

.command-actions {
  display: flex;
  gap: 4px;
}

.mobile-command-actions {
  gap: 8px;
}

.mobile-add-btn {
  width: 100%;
  min-height: 48px;
}

.command-tip {
  margin-top: 12px;
}

/* 移动端优化 */
.mobile-toolbar {
  display: flex;
  justify-content: center;
  margin-bottom: 16px;
  padding: 12px;
  background: var(--background-light);
  border-radius: var(--border-radius);
  position: relative;
  z-index: 10;
}

.mobile-btn {
  min-height: 48px;
  font-size: 16px;
  font-weight: 500;
  width: 100%;
  border-radius: var(--border-radius);
}

/* 表单元素优化 */
.publish-form-content :deep(.el-form-item) {
  margin-bottom: 20px;
}

.publish-form-content :deep(.el-form-item__label) {
  font-size: 16px;
  font-weight: 500;
  color: var(--text-regular);
  padding: 0 8px 0 0;
}

.publish-form-content :deep(.el-input__inner) {
  min-height: 48px;
  font-size: 16px;
  border-radius: var(--border-radius);
}

.publish-form-content :deep(.el-textarea__inner) {
  min-height: 120px;
  font-size: 16px;
  border-radius: var(--border-radius);
}

.publish-form-content :deep(.el-select) {
  border-radius: var(--border-radius);
}

.publish-form-content :deep(.el-select__inner) {
  min-height: 48px;
  font-size: 16px;
}

.publish-form-content :deep(.el-input__suffix-inner) {
  padding: 0 8px;
}

.publish-form-content :deep(.el-input__clear) {
  font-size: 18px;
  width: 24px;
  height: 24px;
}

.switch-item {
  padding-left: 0 !important;
}

.switch-item :deep(.el-form-item__content) {
  display: flex;
  align-items: center;
}

.publish-form-content :deep(.el-switch) {
  margin-right: 12px;
  transform: scale(1.2);
}

.checkbox-item :deep(.el-checkbox__label) {
  font-size: 15px;
  color: var(--text-regular);
}

.publish-button {
  margin-bottom: 0;
}

.publish-btn {
  width: 100%;
  min-height: 52px;
  font-size: 16px;
  font-weight: 500;
  border-radius: var(--border-radius);
}

/* 脉冲动画效果 */
.pulse-effect {
  position: relative;
  overflow: hidden;
}

.pulse-effect::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 5px;
  height: 5px;
  background: rgba(255, 255, 255, 0.5);
  opacity: 0;
  border-radius: 100%;
  transform: scale(1, 1) translate(-50%, -50%);
  transform-origin: 50% 50%;
}

.pulse-effect:focus::after {
  animation: pulse-btn var(--pulse-duration) ease-out;
}

@keyframes pulse-btn {
  0% {
    transform: scale(0.8, 0.8) translate(-50%, -50%);
    opacity: 0.5;
  }
  100% {
    transform: scale(15, 15) translate(-50%, -50%);
    opacity: 0;
  }
}

/* 触摸优化 */
.touchable {
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.mobile-input {
  --el-input-height: 52px;
}

.mobile-select {
  --el-input-height: 52px;
}

.mobile-textarea {
  min-height: 180px;
  font-size: 16px;
  line-height: 1.6;
}

.mobile-only {
  display: none;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .main-content {
    flex-direction: column;
    gap: 20px;
  }
  
  .side-panels {
    width: 100%;
  }
  
  .mobile-toolbar {
    flex-direction: column;
    gap: 12px;
    align-items: stretch;
    margin-bottom: 20px;
  }
  
  .commands-header {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }
  
  .command-item {
    justify-content: space-between;
    padding: 16px;
  }
  
  .publish-form-content :deep(.el-form-item) {
    margin-bottom: 24px;
  }
  
  .publish-form-content :deep(.el-form-item__label) {
    font-size: 16px;
    padding-right: 0;
    margin-bottom: 8px;
  }
  
  .publish-form-content :deep(.el-select) {
    width: 100%;
  }
  
  .history-list {
    max-height: 300px;
  }
  
  .history-item {
    padding: 16px;
    flex-direction: column;
    gap: 12px;
  }
  
  .history-actions {
    flex-direction: row;
    justify-content: flex-end;
  }
  
  .mobile-only {
    display: block;
  }
}

@media (min-width: 769px) {
  .mobile-toolbar {
    display: none;
  }
  
  .toolbar {
    display: flex;
  }
}

/* 平板竖屏优化 */
@media (min-width: 768px) and (max-width: 1024px) and (orientation: portrait) {
  .main-content {
    flex-direction: column;
  }
  
  .side-panels {
    width: 100%;
  }
}

/* 打印样式优化 */
@media print {
  .command-actions,
  .history-actions,
  .mobile-toolbar,
  .toolbar {
    display: none;
  }
  
  .command-item,
  .history-item {
    border: 1px solid #000;
    break-inside: avoid;
  }
}

/* 减少动画偏好设置支持 */
@media (prefers-reduced-motion: reduce) {
  .pulse-effect::after {
    display: none;
  }
  
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
</style>
